package com.mbc.hr.manager;

import java.sql.SQLException;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.mbc.common.exception.DataDuplicationException;
import com.mbc.common.exception.ForeignConflictException;
import com.mbc.common.manager.AbstractMgr;
import com.mbc.common.param.CriteriaParams;
import com.mbc.common.utils.KeyGenerator;
import com.mbc.hr.data.AttendancePenaltyDataList;
import com.mbc.hr.entities.AttendancePenalty;
import com.mbc.hr.entities.AttendancePenaltyDetail;
import com.mbc.hr.entities.EarlyDeparturePenaltyDetail;


public class AttendancePenaltyMgr extends AbstractMgr {
//	protected EntityManager entityManager;
	public AttendancePenaltyMgr(){
		
	}
	
	public AttendancePenaltyMgr(String sessionID){
		this.sessionId = sessionID;
	}
	
	public void create(AttendancePenalty attendancePenalty)throws Exception{
		openConnection();
		try {
			beginTransaction();
			long l_key  = KeyGenerator.generateKey(entityManager);
			
			//long l_key = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
			
			attendancePenalty.setAttendancePenaltyID(l_key);
			entityManager.persist(attendancePenalty);
			
			for (AttendancePenaltyDetail l_detail : attendancePenalty.getDetails()) {
				l_detail.setAttendancePenaltyID(l_key);
				entityManager.persist(l_detail);
			}
			for(EarlyDeparturePenaltyDetail l_earlyDetail:attendancePenalty.getEarlydetails()){
				l_earlyDetail.setAttendancePenaltyID(l_key);
				entityManager.persist(l_earlyDetail);
			}
			
			commitTransaction();
		}
		catch (Exception e) {
			rollbackTransaction();
			if(DataDuplicationException.isUniqueKyeError(e))
				throw new DataDuplicationException(e.getMessage());
			else
				throw e;
		} finally{
			closeConnection();
		}
	}
	
	public void update(AttendancePenalty attendancePenalty)throws Exception{
		openConnection();
		try {
			beginTransaction();
			
			entityManager.merge(attendancePenalty);
		
			entityManager.createNamedQuery("AttendancePenaltyDetail.deleteByPenaltyID")
				.setParameter("attendancePenaltyID", attendancePenalty.getAttendancePenaltyID())
				.executeUpdate();

			for(EarlyDeparturePenaltyDetail l_earlyDetail:attendancePenalty.getEarlydetails()){
				entityManager.createNamedQuery("EarlyDeparturePenaltyDetail.deleteByPenaltyID")
				.setParameter("attendancePenaltyID", l_earlyDetail.getAttendancePenaltyID())
				.executeUpdate();
			}
			
			for (AttendancePenaltyDetail l_detail : attendancePenalty.getDetails()) {
				l_detail.setAttendancePenaltyID(attendancePenalty.getAttendancePenaltyID());
				entityManager.persist(l_detail);
			}
			for(EarlyDeparturePenaltyDetail l_earlyDetail:attendancePenalty.getEarlydetails()){
				l_earlyDetail.setAttendancePenaltyID(attendancePenalty.getAttendancePenaltyID());
				entityManager.persist(l_earlyDetail);
			}
					
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public void delete(long attendancePenaltyID)throws Exception{
		openConnection();
		try {
			beginTransaction();
			entityManager.createNamedQuery("AttendancePenaltyDetail.deleteByPenaltyID")
				.setParameter("attendancePenaltyID", attendancePenaltyID)
				.executeUpdate();
			AttendancePenalty l_attendancePenalty = entityManager.find(AttendancePenalty.class, attendancePenaltyID);
			entityManager.remove(l_attendancePenalty);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			if(e.getCause().getCause().getCause() instanceof SQLException){
				if(ForeignConflictException.FOREIGN_CONFLICT_ERROR_CODE == ((SQLException)e.getCause().getCause().getCause()).getErrorCode())
					throw new ForeignConflictException(e);
				else
					throw e;
			}
			else
				throw e;
		} finally {
			closeConnection();
		}
	}
	
	public AttendancePenalty find(long attendancePenaltyID)throws Exception{
		openConnection();
		try {
			AttendancePenalty l_attendancePenalty = entityManager.find(AttendancePenalty.class, attendancePenaltyID);
			if(l_attendancePenalty != null){
				l_attendancePenalty.setDetails(entityManager.createNamedQuery("AttendancePenaltyDetail.findByPenaltyID", AttendancePenaltyDetail.class)
						.setParameter("attendancePenaltyID", attendancePenaltyID)
						.getResultList());
				l_attendancePenalty.setEarlydetails(entityManager.createNamedQuery("EarlyDeparturePenaltyDetail.findByPenaltyID",EarlyDeparturePenaltyDetail.class)
						.setParameter("attendancePenaltyID",attendancePenaltyID).getResultList());
			}
			return l_attendancePenalty;
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public List<AttendancePenalty> findAll()throws Exception{
		openConnection();
		try {
			return entityManager.createNamedQuery("AttendancePenalty.findAll", AttendancePenalty.class).getResultList();
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public List<AttendancePenaltyDetail> findDetails(long attendancePenaltyID)throws Exception{
		openConnection();
		try {
			return entityManager.createNamedQuery("AttendancePenaltyDetail.findByPenaltyID", AttendancePenaltyDetail.class)
					.setParameter("attendancePenaltyID", attendancePenaltyID)
					.getResultList();
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public AttendancePenaltyDataList getAttendancePenalty(CriteriaParams cri)throws Exception{
		openConnection();
		try {
			CriteriaBuilder l_criBuilder = entityManager.getCriteriaBuilder();
            CriteriaQuery<AttendancePenalty> l_cri = l_criBuilder.createQuery(AttendancePenalty.class);
            Root<AttendancePenalty> l_root = l_cri.from(AttendancePenalty.class);
            l_cri.select(l_root);
            Predicate l_Predicate = l_criBuilder.or(
                    l_criBuilder.like(l_root.<String>get("penaltyCode"), "%" + cri.getKeyword() + "%"),
                    l_criBuilder.like(l_root.<String>get("description"), "%" + cri.getKeyword() + "%")
            );
            l_cri.where(l_Predicate);

            List<AttendancePenalty> l_entityList = entityManager.createQuery(l_cri)
                    .setFirstResult(cri.getIndex())
                    .setMaxResults(cri.getSize())
                    .getResultList();
            
            AttendancePenaltyDataList l_dataList = new AttendancePenaltyDataList();
            l_dataList.setEntityList(l_entityList);
            
            if(cri.getIndex() == 0){
            	CriteriaQuery<Long> l_countQuery = l_criBuilder.createQuery(Long.class);
            	l_root = l_countQuery.from(AttendancePenalty.class);
            	l_countQuery.select(l_criBuilder.count(l_root));
            	l_countQuery.where(l_Predicate);
            	l_dataList.setTotalRecord(entityManager.createQuery(l_countQuery).getSingleResult());
            }
            
			return l_dataList;
		} catch (Exception e) {
			throw e;
		} finally{
			closeConnection();
		}
	}

}
